//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	FormsBuilder.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using Smart.Common.Rules;

namespace Smart.Common.Forms
{
	/// <summary>
	/// Forms builder (create form in container)
	/// </summary>
	public abstract class FormsBuilder
	{
		/// <summary>
		/// Forms context
		/// </summary>
		public FormsContext Ctx { get; set; }

		/// <summary>
		/// Parse source (create new form using builder)
		/// </summary>
		public abstract MetaForms ParseFormsDefinition(object source);

		/// <summary>
		/// Choose form from forms collection using rules
		/// </summary>
		public virtual MetaForm ChooseForm()
		{
			if (Ctx.ChooseRulesServiceName.IsNullOrEmpty())
				throw new ArgumentNullException("Ctx.ChooseRulesServiceName");

			Ctx.ChooseRulesService = GetFormsRulesService();

			if (Ctx.ChooseRulesService == null)
				return null;

			var ri = GetFormsRulesInstance();

			if (!Ctx.ChooseRulesService.Execute(ri))
				throw new NotSupportedException("Ctx.ChooseRulesService.Execute(ri)");

			var form = Ctx.Forms.Forms.Find(cform => cform.Name.EqIC(ri.ChoosedFormName));

			if (form == null)
				throw new KeyNotFoundException("ChoosedFormName");

			return form;
		}

		/// <summary>
		/// Return new RulesService
		/// </summary>
		/// <returns></returns>
		public virtual IRulesService GetFormsRulesService()
		{
			if (Ctx.ChooseRulesServiceName.IsNullOrEmpty())
				throw new ArgumentNullException("Ctx.ChooseRulesServiceName");

			return SPServices.RulesFactory.GetService(Ctx.ChooseRulesServiceName);
		}

		/// <summary>
		/// Return new RulesInstance
		/// </summary>
		public virtual FormsChooseRulesInstance GetFormsRulesInstance()
		{
			return new FormsChooseRulesInstance(Ctx.Forms.Rules, Ctx);
		}

		/// <summary>
		/// Load entity and user supplied values to form
		/// </summary>
		public abstract void FillFormValues();

		/// <summary>
		/// Process form after filling with values
		/// </summary>
		public abstract void ProcessFormAfterFill();

		/// <summary>
		/// Detect forms chooser rules service name
		/// </summary>
		public virtual string DetectFormsChooserRulesServiceName()
		{
			return Const.Forms.DefaultRulesServiceName;
		}

		/// <summary>
		/// Execute choose rule condition function
		/// </summary>
		public virtual bool ExecuteFunction(string functionName, string[] functionArgs)
		{
			bool handled;

			var res = Ctx.Service.ExecuteFunction(functionName, functionArgs, out handled);

			if (!handled)
				throw new NotSupportedException(functionName);

			return res;
		}

		/// <summary>
		/// Forms builder (create form in container)
		/// </summary>
		protected FormsBuilder(FormsContext ctx)
		{
			Ctx = ctx;
		}
	}
}